package com.bsoft.utils;

import com.bsoft.service.impl.ThirdLevelPubHosPerformanceAssessServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * VCS文件生成工具类，支持生成VCS文件并压缩为ZIP
 */
public class VcsGeneratorUtil {
    private static Logger logger = LoggerFactory.getLogger(VcsGeneratorUtil.class);
    // 单元格分隔符（使用制表符\t，适合表格工具识别）
    private static final String SEPARATOR = "\t";
    // 日期格式，用于生成唯一文件名
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    /**
     * 生成VCS文件
     *
     * @param dataList 字典数据列表
     * @param filePath 输出文件路径
     * @throws IOException 写入文件时可能发生的异常
     */
    public static void generateVcs(List<Map<String, Object>> dataList, String filePath) throws IOException {
        if (dataList == null || dataList.isEmpty()) {
            throw new IllegalArgumentException("数据列表不能为空");
        }

        try (BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(filePath), StandardCharsets.UTF_8))) {
            // 1. 收集所有map中的key并去重（保持插入顺序）
            Set<String> allKeys = new LinkedHashSet<>();
            for (Map<String, Object> record : dataList) {
                allKeys.addAll(record.keySet());
            }
            List<String> headerKeys = new ArrayList<>(allKeys);

            // 2. 写入首行表头
            writeHeader(writer, headerKeys);

            // 3. 写入数据行
            for (Map<String, Object> record : dataList) {
                writeRecordValues(writer, headerKeys, record);
            }
        }
    }

    /**
     * 生成VCS文件并压缩为ZIP
     *
     * @param dataList         数据列表
     * @param orderVcsFileName 基础文件名（不含后缀）
     * @throws IOException 处理过程中的IO异常
     */
    public static void generateVcsZip(String hosName, String hosCode, int i, List<Map<String, Object>> dataList, String orderVcsFileName, String zipPath,String yearMonth) throws Exception {
        if (dataList == null || dataList.isEmpty()) {
            throw new IllegalArgumentException("数据列表不能为空");
        }

        // 确保目录存在
        Path directory = Paths.get(zipPath);
        if (!Files.exists(directory)) {
            Files.createDirectories(directory);
        }

        // 生成唯一标识符（避免文件名冲突）
        String timestamp = DATE_FORMAT.format(new Date());
        String uniqueId = timestamp + "_" + UUID.randomUUID().toString().substring(0, 8);

        // 1. 创建临时VCS文件（使用系统临时目录） C:\Users\用户名\AppData\Local\Temp
        String tempVcsFileName = orderVcsFileName + "_" + uniqueId + "_" +i;
        File tempVcsFile = File.createTempFile(tempVcsFileName, ".vcs");
        String vcsFileName = orderVcsFileName + ".vcs"; // ZIP内部的VCS文件名

        try {
            // 2. 生成VCS内容到临时文件
            generateVcs(dataList, tempVcsFile.getAbsolutePath());
            // 3. 创建ZIP文件（保存到当前工作目录）  TCMMS61003_西安中医医院_2024_1.zip
            String zipFilePath = zipPath + hosCode + "_" + hosName + "_" + yearMonth + "_" + i + ".zip";

            try (FileOutputStream fos = new FileOutputStream(zipFilePath);
                 ZipOutputStream zos = new ZipOutputStream(fos, StandardCharsets.UTF_8)) {
                // 4. 添加VCS文件到ZIP
                ZipEntry zipEntry = new ZipEntry(vcsFileName);
                zos.putNextEntry(zipEntry);
                // 5. 写入VCS文件内容到ZIP条目
                Files.copy(tempVcsFile.toPath(), zos);
                zos.closeEntry();
            }

            // 日志：ZIP文件生成成功
            logger.info("ZIP文件生成成功：" + zipFilePath);

        } finally {
            // 6. 删除临时VCS文件（无论是否成功都清理）
            if (tempVcsFile.exists() && !tempVcsFile.delete()) {
                logger.info("临时文件删除失败：" + tempVcsFile.getAbsolutePath());
            }
        }
    }

    private static void writeHeader(BufferedWriter writer, List<String> headerKeys) throws IOException {
        List<String> escapedHeaders = new ArrayList<>();
        for (String key : headerKeys) {
            escapedHeaders.add(escapeSpecialCharacters(key));
        }
        writer.write(String.join(SEPARATOR, escapedHeaders));
        writer.newLine();
    }

    private static void writeRecordValues(BufferedWriter writer, List<String> headerKeys, Map<String, Object> record) throws IOException {
        List<String> values = new ArrayList<>();
        for (String key : headerKeys) {
            Object valueObj = record.getOrDefault(key, "");
            String value = valueObj == null ? "" : valueObj.toString();
            values.add(escapeSpecialCharacters(value));
        }
        writer.write(String.join(SEPARATOR, values));
        writer.newLine();
    }

    private static String escapeSpecialCharacters(String input) {
        if (input == null) return "";
        return input.replace("\\", "\\\\")
                .replace(SEPARATOR, "\\" + SEPARATOR)
                .replace(";", "\\;")
                .replace("\n", "\\n")
                .replace("\r", "");
    }
}
